package com.whately.core.base.keygen;

import com.whately.core.base.exception.ServiceException;
import com.whately.core.base.utils.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.atomic.AtomicBoolean;


/**
 * 获取机器码
 * 越早加载越好 : BeanPostProcessor 优先加载
 */
@Component
@Slf4j
public class WhatelyMachineCodeHelper implements BeanPostProcessor {
    private final AtomicBoolean init = new AtomicBoolean(false);

    private String desc;

    //枚举出来所有ip
    @Value("${snow.flake.ips:}")
    private String snowFlakeIpVsMachineCode;

    //ip，ts ，workid
    private static int machineCodeZeroToNine = -1;


    @PostConstruct
    public void init(){
        log.info("************ snowFlakeIpVsMachineCode = {}", snowFlakeIpVsMachineCode);
        if(!init.compareAndSet(false,true)){
            throw new ServiceException(400,"register node again error");
        }

        String ip = IpUtils.getLocalHostIp();
        if(StringUtils.isBlank(ip)){
            throw new RuntimeException("register work node error,ip is blank");
        }

        StringBuilder sb=new StringBuilder();

        //根据ip生成全局的唯一work-id
        //暂时用ip分割相加的算法 192.168.1.3 和 192.168.3.1会失败
        if(StringUtils.isNotBlank(snowFlakeIpVsMachineCode)&& snowFlakeIpVsMachineCode.indexOf(ip)>=0){
            String[] ipAndWorkIdAry= snowFlakeIpVsMachineCode.split(",");
            for(String ipAndWorkId:ipAndWorkIdAry){
                String[] tmp = ipAndWorkId.split("-");
                if(tmp[0].equals(ip)){
                    machineCodeZeroToNine = Integer.parseInt(tmp[1]);
                    break;
                }
            }
        }else{
            String[] ipAry=ip.split("\\.");
            machineCodeZeroToNine = Integer.parseInt(ipAry[3].substring(ipAry[3].length()-1));
        }


        if(machineCodeZeroToNine <0||machineCodeZeroToNine >9){
            log.error("register work node fail,ip {},machineCodeZeroToNine between [0-9],but now is {}",ip,machineCodeZeroToNine);
            throw new RuntimeException("register work node fail");
        }

        sb.append("ip: ").append(ip).append("; ");
        sb.append("machineCodeZeroToNine: ").append(machineCodeZeroToNine).append("; ");
        desc = sb.toString();

        log.info("WhatelyMachineCodeHelper desc is  {}",desc);

    }

    /**
     * 机器码 0-9 ，暂时只支持10台机器
     * @return
     */
    public static int getMachineCode(){
        return machineCodeZeroToNine==-1?0:machineCodeZeroToNine;
    }


    public String desc(){
        return desc;
    }
}
